__author__ = "jimmyorr@gmail.com (Jimmy Orr), chedbrandh@gmail.com (Christofer Hedbrandh)"

import time
import random

from dropio.client import *
from client_test_utils import *

class DropIoClientDropActionsTestCase(DropIoClientBaseTestCase):
    
    ################
    # create_drop()
    ################
    
    def test_create_drop(self):
        for c in filter(None, [self.client, self.secure_client]):
            param_dict = CREATE_DROP_PARAM_DICT
            drop = c.create_drop(drop_name = self.available_drop_name, **param_dict)
            self.failUnlessEqual(self.available_drop_name, drop.name)
            self.failUnlessEqual(param_dict["description"], drop.description)
            self.failUnlessEqual(int(param_dict["max_size"])*(2**20), int(drop.max_bytes))
            self.failUnlessEqual(drop.asset_count, 0)
            self.failUnlessEqual(drop.current_bytes, 0)
            self.failUnlessEqual(drop.email, self.available_drop_name + "." +  param_dict["email_key"] + "@drop.io")
            self.failUnless(drop.expires_at is not None)
            # clean up
            c.delete_drop(drop = drop)
    
    def test_create_drop_from_drop_object(self):
        for c in filter(None, [self.client, self.secure_client]):
            param_dict = CREATE_DROP_PARAM_DICT
            drop = c.create_drop(drop_name = self.available_drop_name, **param_dict)
            c.delete_drop(drop = drop)
            drop2 = c.create_drop(drop = drop)
            self.failUnlessEqual(drop.name, drop2.name)
            self.failUnlessEqual(drop.description, drop2.description)
            self.failUnlessEqual(drop.max_bytes, drop2.max_bytes)
            self.failUnlessEqual(drop.email, drop2.email)
            c.delete_drop(drop = drop2)

    def test_create_drop_illegal_drop_name(self):
        for c in filter(None, [self.client, self.secure_client]):
            # todo does not raise an error
            self.assertRaises(ForbiddenError, c.create_drop, drop_name = "!@#$%^&")
    
    #############
    # get_drop()
    #############
    
    def test_get_drop_self_valid_drop_name(self):
        for c in filter(None, [self.client, self.secure_client]):
            param_dict = CREATE_DROP_PARAM_DICT
            drop = c.create_drop(drop_name = self.available_drop_name, **param_dict)
            drop2 = c.get_drop(drop_name = drop.name)
            # todo created_at parameter format varies randomly, Bug #628
            self.failUnlessEqual(drop, drop2)
            self.failUnless(drop2)
    
    def test_get_drop_no_such_drop_name(self):
        for c in filter(None, [self.client, self.secure_client]):
            self.assertRaises(ResourceNotFoundError, c.get_drop, drop_name = self.available_drop_name)
    
    def test_get_drop_unauthorized(self):
        assert self.client2 or self.secure_client2, "no second key specified"
        for c in filter(None, [self.client, self.secure_client]):
            for c2 in filter(None, [self.client2, self.secure_client2]):
                drop = c.create_drop(drop_name = self.available_drop_name)
                self.assertRaises(ForbiddenError, c2.get_drop, drop_name = drop.name)
    
    ###############
    # update_drop()
    ###############
    
    def test_update_drop(self):
        for c in filter(None, [self.client, self.secure_client]):
            param_dict = CREATE_DROP_PARAM_DICT
            drop = c.create_drop(drop_name = self.available_drop_name)
            drop2 = c.update_drop(drop_name = drop.name, **param_dict)
            drop3 = c.get_drop(drop_name = self.available_drop_name)
            self.failUnlessEqual(param_dict["description"], drop2.description)
            # todo max_size does not work for update
            self.failUnlessEqual(int(param_dict["max_size"])*(2**20), int(drop2.max_bytes))
            self.failUnlessEqual(drop3.email, self.available_drop_name + "." +  param_dict["email_key"] + "@drop.io")
    
    def test_update_drop_from_drop_object(self):
        for c in filter(None, [self.client, self.secure_client]):
            param_dict = CREATE_DROP_PARAM_DICT
            drop = c.create_drop(drop_name = self.available_drop_name)
            drop.description = param_dict["description"]
            drop.email_key = param_dict["email_key"]
            drop2 = c.update_drop(drop = drop)
            drop3 = c.get_drop(drop = drop)
            self.failUnlessEqual(param_dict["description"], drop2.description)
            # todo max_size does not work for update
            self.failUnlessEqual(int(param_dict["max_size"])*(2**20), int(drop2.max_bytes))
            self.failUnlessEqual(drop3.email, self.available_drop_name + "." +  param_dict["email_key"] + "@drop.io")
    
    def test_update_drop_name(self):
        for c in filter(None, [self.client, self.secure_client]):
            new_drop_name = self.available_drop_name2
            test_description = "test_description"
            drop = c.create_drop(drop_name = self.available_drop_name, description = test_description)
            drop2 = c.update_drop(drop_name = drop.name, new_name = new_drop_name)
            drop3 = c.get_drop(drop_name = new_drop_name)
            self.failUnlessEqual(test_description, drop3.description)
            # clean up
            c.delete_drop(drop_name = new_drop_name)
    
    def test_update_drop_no_such_drop_name(self):
        for c in filter(None, [self.client, self.secure_client]):
            self.assertRaises(ResourceNotFoundError, c.update_drop, drop_name = self.available_drop_name)
    
    def test_update_drop_unauthorized(self):
        assert self.client2 or self.secure_client2, "no second key specified"
        for c in filter(None, [self.client, self.secure_client]):
            for c2 in filter(None, [self.client2, self.secure_client2]):
                drop = c.create_drop(drop_name = self.available_drop_name)
                self.assertRaises(ForbiddenError, c2.update_drop, drop_name = drop.name)
    
    ################
    # delete_drop()
    ################
    
    def test_delete_drop(self):
        for c in filter(None, [self.client, self.secure_client]):
            drop = c.create_drop(drop_name = self.available_drop_name)
            c.delete_drop(drop = drop)
            self.assertRaises(ResourceNotFoundError, c.get_drop, drop = drop)
    
    def test_delete_drop_no_such_drop_name(self):
        for c in filter(None, [self.client, self.secure_client]):
            self.assertRaises(ResourceNotFoundError, c.delete_drop, drop_name = self.available_drop_name)
    
    def test_delete_drop_unauthorized(self):
        assert self.client2 or self.secure_client2, "no second key specified"
        for c in filter(None, [self.client, self.secure_client]):
            for c2 in filter(None, [self.client2, self.secure_client2]):
                drop = c.create_drop(drop_name = self.available_drop_name)
                self.assertRaises(ForbiddenError, c2.delete_drop, drop_name = drop.name)
    
    ################
    # empty_drop()
    ################
    
    def test_empty_drop(self):
        for c in filter(None, [self.client, self.secure_client]):
            drop = c.create_drop(drop_name = self.available_drop_name)
            c.create_note(drop = drop, contents = "asdfasdfasdf")
            c.create_link(drop = drop, url = "http://foo.com")
            c.create_file(drop = drop, file_name = TEST_IMAGE_JPG)
            self.failUnlessEqual(len(list(c.get_assets(drop = drop))), 3)
            c.empty_drop(drop = drop)
            self.failUnlessEqual(len(list(c.get_assets(drop = drop))), 0)
    
    def test_empty_drop_no_such_drop_name(self):
        for c in filter(None, [self.client, self.secure_client]):
            self.assertRaises(ResourceNotFoundError, c.empty_drop, drop_name = self.available_drop_name)
    
    def test_empty_drop_unauthorized(self):
        assert self.client2 or self.secure_client2, "no second key specified"
        for c in filter(None, [self.client, self.secure_client]):
            for c2 in filter(None, [self.client2, self.secure_client2]):
                drop = c.create_drop(drop_name = self.available_drop_name)
                self.assertRaises(ForbiddenError, c2.empty_drop, drop_name = drop.name)
    
    ################
    # get_drops()
    ################
    
    def test_get_drops(self):
        for c in filter(None, [self.client, self.secure_client]):
            num_old_drops = len(list(c.get_drops()))
            # create at least 3 new drops, total > 30 because of 30 retured drops per page
            num_new_drops = max(31 - len(list(c.get_drops())), 3)
            random_drop_names = []
            for i in range(num_new_drops):
                random_drop_name = self.available_drop_name + str(random.randint(0, 2**20))
                c.create_drop(drop_name = random_drop_name)
                time.sleep(PROCESS_WAIT_TIME)
                random_drop_names.append(random_drop_name)
            self.failUnlessEqual(num_new_drops + num_old_drops, len(list(c.get_drops())))
            for random_drop_name in random_drop_names:
                self.failUnless(random_drop_name in [x.name for x in c.get_drops()])
            # clean up
            for random_drop_name in random_drop_names:
                time.sleep(PROCESS_WAIT_TIME)
                c.delete_drop(drop_name = random_drop_name)
